import {APP_INITIALIZER, ModuleWithProviders, NgModule, Optional, SkipSelf} from '@angular/core';
import {AuthConfig, DateTimeProvider, OAuthModule, OAuthModuleConfig, OAuthStorage} from 'angular-oauth2-oidc';
import {HttpClientModule} from "@angular/common/http";
import {AuthService} from "./auth.service";
import {AuthGuard} from "./auth.guard";
import {AuthWithForcedLoginGuard} from "./auth-with-forced-login.guard";
import {authAppInitializerFactory} from "./auth-app-initiatizer.factory";
import {authConfig} from "./auth-config";
import {authModuleConfig} from "./auth-module-config";
import {CustomDateTimeProvider} from "../shared/date/custom-date-time-provider";
import {AclService} from "../ACL-servie/acl.service";
import {NgxPermissionsModule} from "ngx-permissions";


// We need a factory since localStorage is not available at AOT build time
export function storageFactory(): OAuthStorage {
  return localStorage;
}

@NgModule({
  declarations: [
    //CorsHandleDirective
  ],
  imports: [
    HttpClientModule,
    OAuthModule.forRoot(
      {
        resourceServer: authModuleConfig.resourceServer
      }
    ),
    // permission
    //NgxPermissionsModule.forRoot(),  //意味着它必须在应用的根模块处导入,这个类只创建一次
  ],
  exports: [
    //CorsHandleDirective
  ],
  providers: [
    AuthService,
    AclService,
    AuthGuard,
    AuthWithForcedLoginGuard,
    { provide: DateTimeProvider, useClass: CustomDateTimeProvider } // <- add this
  ],
})

export class CoreModule {
  // forRoot() 方法返回一个模块，该模块包含一个提供程序数组，该数组包含一个提供程序，该提供程序是一个函数，该函数返回一个模块，该模块包含一个提供程序数组，该数组包含一个提供程序，该提供程序是一个函数，该函数返回一个模块，该模块包含一个提供程序数组，该数组包含一个提供程序，该提供程序是一个函数，该函数返回一个模块，该模块包含一个
  static forRoot():  ModuleWithProviders<CoreModule>  {
    return {
      ngModule: CoreModule,
      providers: [
        {provide: APP_INITIALIZER, useFactory: authAppInitializerFactory, deps: [AuthService], multi: true},
        {provide: AuthConfig, useValue: authConfig},
        {provide: OAuthModuleConfig, useValue: authModuleConfig},
        {provide: OAuthStorage, useFactory: storageFactory},
      ],
    };
  }

  constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
    if (parentModule) {
      console.log("已经加载核心模块=====")
      throw new Error(
        'CoreModule is already loaded. Import it in the AppModule only');
    }
  }
}
